package jmercury;

import java.util.Calendar;
import java.util.GregorianCalendar;

public class EMeter {

    private int idInDB;
    private String counterName;
    private byte addressOnBus = 0;
    private M233Lib m233lib;
    private int addressInMem3 = 0;
    private Boolean overloadBit = null;
    private int Ki = 1;
    private int Ku = 1;
    private int meterConst = 1000;

    public EMeter(String counterName, int Ki, int Ku, String comPort, int addressOnBus, int idInDB) {
        this.counterName = counterName;
        this.addressOnBus = (byte) addressOnBus;
        this.Ki = Ki;
        this.Ku = Ku;
        this.m233lib = new M233Lib(comPort);
        this.idInDB = idInDB;
    }

    public String getMeterName() {
        return counterName;
    }

    public int getMeterKi() {
        return Ki;
    }

    public int getMeterKu() {
        return Ku;
    }

    public String getMeterComPort() {
        return m233lib.getComPort();
    }

    public int getIdInDB() {
        return idInDB;
    }

    @Override
    public String toString() {
        return counterName;
    }

    int getDelay() {
        return m233lib.getDelay();
    }

    public void setDelay(int delay) {
        m233lib.setDelay(delay);
    }

    public Double getFreq() {
        double freq = 0d;
        byte[] cmd = new byte[]{
            addressOnBus, // Адрес
            (byte) 0x08, // Код запроса
            (byte) 0x11,
            (byte) 0x40,
            (byte) 0x00, // CRC ставится автоматом в M233Lib
            (byte) 0x00};// CRC ставится автоматом в M233Lib
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp != null && resp.length == 6) {
            freq += (resp[3] & 0xFF) << 8;
            freq += (resp[2] & 0xFF);
            freq = freq / 100;
        } else {
            return null;
        }
        return freq;
    }

    public Double getU1() {
        double u1 = 0d;
        byte[] cmd = new byte[]{
            addressOnBus,
            (byte) 0x08,
            (byte) 0x11,
            (byte) 0x11,
            (byte) 0x00,
            (byte) 0x00};
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp != null && resp.length == 6) {
            u1 += (resp[3] & 0xFF) << 8;
            u1 += (resp[2] & 0xFF);
            u1 /= 100;
            u1 *= Ku;
        } else {
            return null;
        }
        return u1;
    }

    public Double getU2() {
        double u2 = 0d;
        byte[] cmd = new byte[]{
            addressOnBus,
            (byte) 0x08,
            (byte) 0x11,
            (byte) 0x12,
            (byte) 0x00,
            (byte) 0x00};
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp != null && resp.length == 6) {
            u2 += (resp[3] & 0xFF) << 8;
            u2 += (resp[2] & 0xFF);
            u2 /= 100;
            u2 *= Ku;
        } else {
            return null;
        }
        return u2;
    }

    public Double getU3() {
        double u3 = 0d;
        byte[] cmd = new byte[]{
            addressOnBus,
            (byte) 0x08,
            (byte) 0x11,
            (byte) 0x13,
            (byte) 0x00,
            (byte) 0x00};
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp != null && resp.length == 6) {
            u3 += (resp[3] & 0xFF) << 8;
            u3 += (resp[2] & 0xFF);
            u3 /= 100;
            u3 *= Ku;
        } else {
            return null;
        }
        return u3;
    }

    public Double getI1() {
        double i1 = 0d;
        byte[] cmd = new byte[]{
            addressOnBus,
            (byte) 0x08,
            (byte) 0x11,
            (byte) 0x21,
            (byte) 0x00,
            (byte) 0x00};
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp != null && resp.length == 6) {
            i1 += (resp[3] & 0xFF) << 8;
            i1 += (resp[2] & 0xFF);
            i1 /= 1000;
            i1 *= Ki;
        } else {
            return null;
        }
        return i1;
    }

    public Double getI2() {
        double i2 = 0d;
        byte[] cmd = new byte[]{
            addressOnBus,
            (byte) 0x08,
            (byte) 0x11,
            (byte) 0x22,
            (byte) 0x00,
            (byte) 0x00};
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp != null && resp.length == 6) {
            i2 += (resp[3] & 0xFF) << 8;
            i2 += (resp[2] & 0xFF);
            i2 /= 1000;
            i2 *= Ki;
        } else {
            return null;
        }
        return i2;
    }

    public Double getI3() {
        double i3 = 0d;
        byte[] cmd = new byte[]{
            addressOnBus,
            (byte) 0x08,
            (byte) 0x11,
            (byte) 0x23,
            (byte) 0x00,
            (byte) 0x00};
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp != null && resp.length == 6) {
            i3 += (resp[3] & 0xFF) << 8;
            i3 += (resp[2] & 0xFF);
            i3 /= 1000;
            i3 *= Ki;
        } else {
            return null;
        }
        return i3;
    }

    public Double getP1() {
        double p1 = 0d;
        byte[] cmd = new byte[]{
            addressOnBus,
            (byte) 0x08,
            (byte) 0x11,
            (byte) 0x01,
            (byte) 0x00,
            (byte) 0x00};
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp != null && resp.length == 6) {
            p1 += (resp[3] & 0xFF) << 8;
            p1 += (resp[2] & 0xFF);
            if ((resp[1] & 0x80) == 0x80) {
                p1 /= -100;
            } else {
                p1 /= 100;
            }
            p1 *= Ki;
        } else {
            return null;
        }
        return p1;
    }

    public Double getP2() {
        double p2 = 0d;
        byte[] cmd = new byte[]{
            addressOnBus,
            (byte) 0x08,
            (byte) 0x11,
            (byte) 0x02,
            (byte) 0x00,
            (byte) 0x00};
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp != null && resp.length == 6) {
            p2 += (resp[3] & 0xFF) << 8;
            p2 += (resp[2] & 0xFF);
            if ((resp[1] & 0x80) == 0x80) {
                p2 /= -100;
            } else {
                p2 /= 100;
            }
            p2 *= Ki;
        } else {
            return null;
        }
        return p2;
    }

    public Double getP3() {
        double p3 = 0d;
        byte[] cmd = new byte[]{
            addressOnBus,
            (byte) 0x08,
            (byte) 0x11,
            (byte) 0x03,
            (byte) 0x00,
            (byte) 0x00};
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp != null && resp.length == 6) {
            p3 += (resp[3] & 0xFF) << 8;
            p3 += (resp[2] & 0xFF);
            if ((resp[1] & 0x80) == 0x80) {
                p3 /= -100;
            } else {
                p3 /= 100;
            }
            p3 *= Ki;
        } else {
            return null;
        }
        return p3;
    }

    public Double getQ1() {
        double q1 = 0d;
        byte[] cmd = new byte[]{
            addressOnBus,
            (byte) 0x08,
            (byte) 0x11,
            (byte) 0x05,
            (byte) 0x00,
            (byte) 0x00};
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp != null && resp.length == 6) {
            q1 += (resp[3] & 0xFF) << 8;
            q1 += (resp[2] & 0xFF);
            if ((resp[1] & 0x40) == 0x40) {
                q1 /= -100;
            } else {
                q1 /= 100;
            }
            q1 *= Ki;
        } else {
            return null;
        }
        return q1;
    }

    public Double getQ2() {
        double q2 = 0d;
        byte[] cmd = new byte[]{
            addressOnBus,
            (byte) 0x08,
            (byte) 0x11,
            (byte) 0x06,
            (byte) 0x00,
            (byte) 0x00};
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp != null && resp.length == 6) {
            q2 += (resp[3] & 0xFF) << 8;
            q2 += (resp[2] & 0xFF);
            if ((resp[1] & 0x40) == 0x40) {
                q2 /= -100;
            } else {
                q2 /= 100;
            }
            q2 *= Ki;
        } else {
            return null;
        }
        return q2;
    }

    public Double getQ3() {
        double q3 = 0d;
        byte[] cmd = new byte[]{
            addressOnBus,
            (byte) 0x08,
            (byte) 0x11,
            (byte) 0x07,
            (byte) 0x00,
            (byte) 0x00};
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp != null && resp.length == 6) {
            q3 += (resp[3] & 0xFF) << 8;
            q3 += (resp[2] & 0xFF);
            if ((resp[1] & 0x40) == 0x40) {
                q3 /= -100;
            } else {
                q3 /= 100;
            }
            q3 *= Ki;
        } else {
            return null;
        }
        return q3;
    }

    public Double getS1() {
        double s1 = 0d;
        byte[] cmd = new byte[]{
            addressOnBus,
            (byte) 0x08,
            (byte) 0x11,
            (byte) 0x09,
            (byte) 0x00,
            (byte) 0x00};
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp != null && resp.length == 6) {
            s1 += (resp[3] & 0xFF) << 8;
            s1 += (resp[2] & 0xFF);
            s1 /= 100;
            s1 *= Ki;
        } else {
            return null;
        }
        return s1;
    }

    public Double getS2() {
        double s2 = 0d;
        byte[] cmd = new byte[]{
            addressOnBus,
            (byte) 0x08,
            (byte) 0x11,
            (byte) 0x0A,
            (byte) 0x00,
            (byte) 0x00};
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp != null && resp.length == 6) {
            s2 += (resp[3] & 0xFF) << 8;
            s2 += (resp[2] & 0xFF);
            s2 /= 100;
            s2 *= Ki;
        } else {
            return null;
        }
        return s2;
    }

    public Double getS3() {
        double s3 = 0d;
        byte[] cmd = new byte[]{
            addressOnBus,
            (byte) 0x08,
            (byte) 0x11,
            (byte) 0x0B,
            (byte) 0x00,
            (byte) 0x00};
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp != null && resp.length == 6) {
            s3 += (resp[3] & 0xFF) << 8;
            s3 += (resp[2] & 0xFF);
            s3 /= 100;
            s3 *= Ki;
        } else {
            return null;
        }
        return s3;
    }

    public AplusRplus getAplusRplusFromReset() {
        double aplus = 0d;
        double rplus = 0d;
        byte[] cmd = new byte[]{
            addressOnBus,
            (byte) 0x05,
            (byte) 0x00,
            (byte) 0x00,
            (byte) 0x00,
            (byte) 0x00};
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp != null) {
            aplus += (resp[2] & 0xFF) << 24;
            aplus += (resp[1] & 0xFF) << 16;
            aplus += (resp[4] & 0xFF) << 8;
            aplus += (resp[3] & 0xFF);
            aplus /= 1000;
            aplus *= Ki;
            rplus += (resp[10] & 0xFF) << 24;
            rplus += (resp[9] & 0xFF) << 16;
            rplus += (resp[12] & 0xFF) << 8;
            rplus += (resp[11] & 0xFF);
            rplus /= 1000;
            rplus *= Ki;
        } else {
            return null;
        }
        return new AplusRplus(aplus, rplus);
    }

    public AplusRplus getAplusRplusYear() {
        double aplus = 0d;
        double rplus = 0d;
        byte[] cmd = new byte[]{
            addressOnBus,
            (byte) 0x05,
            (byte) 0x10,
            (byte) 0x00,
            (byte) 0x00,
            (byte) 0x00};
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp != null) {
            aplus += (resp[2] & 0xFF) << 24;
            aplus += (resp[1] & 0xFF) << 16;
            aplus += (resp[4] & 0xFF) << 8;
            aplus += (resp[3] & 0xFF);
            aplus /= 1000;
            aplus *= Ki;
            rplus += (resp[10] & 0xFF) << 24;
            rplus += (resp[9] & 0xFF) << 16;
            rplus += (resp[12] & 0xFF) << 8;
            rplus += (resp[11] & 0xFF);
            rplus /= 1000;
            rplus *= Ki;
        } else {
            return null;
        }
        return new AplusRplus(aplus, rplus);
    }

    public AplusRplus getAplusRplusMonth(int month) {
        double aplus = 0d;
        double rplus = 0d;
        byte[] cmd = new byte[]{
            addressOnBus,
            (byte) 0x05,
            (byte) 0x30,
            (byte) 0x00,
            (byte) 0x00,
            (byte) 0x00};
        cmd[2] |= month;
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp != null && resp.length == 19) {
            aplus += (resp[2] & 0xFF) << 24;
            aplus += (resp[1] & 0xFF) << 16;
            aplus += (resp[4] & 0xFF) << 8;
            aplus += (resp[3] & 0xFF);
            aplus *= Ki;
            aplus /= 1000;
            rplus += (resp[10] & 0xFF) << 24;
            rplus += (resp[9] & 0xFF) << 16;
            rplus += (resp[12] & 0xFF) << 8;
            rplus += (resp[11] & 0xFF);
            rplus /= 1000;
            rplus *= Ki;
        } else {
            return null;
        }
        return new AplusRplus(aplus, rplus);
    }

    public AplusRplus getAplusRplusMonthBegining(int month) {
        double aplus = 0d;
        double rplus = 0d;
        int addr = 0x0255 + month * 0x55;
        byte addrHi = (byte) (addr >> 8);
        byte addrLo = (byte) addr;
        byte[] cmd = new byte[]{
            addressOnBus,
            (byte) 0x06,
            (byte) 0x02,
            addrHi,
            addrLo,
            (byte) 0x10,
            (byte) 0x00,
            (byte) 0x00};
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp != null) {
            aplus += (resp[2] & 0xFF) << 24;
            aplus += (resp[1] & 0xFF) << 16;
            aplus += (resp[4] & 0xFF) << 8;
            aplus += (resp[3] & 0xFF);
            aplus *= Ki;
            aplus /= 2000;
            rplus += (resp[10] & 0xFF) << 24;
            rplus += (resp[9] & 0xFF) << 16;
            rplus += (resp[12] & 0xFF) << 8;
            rplus += (resp[11] & 0xFF);
            rplus /= 2000;
            rplus *= Ki;
        } else {
            return null;
        }
        return new AplusRplus(aplus, rplus);
    }

    public AplusRplus getAplusRplusNowDay() {
        double aplus = 0d;
        double rplus = 0d;
        byte[] cmd = new byte[]{
            addressOnBus,
            (byte) 0x05,
            (byte) 0x40,
            (byte) 0x00,
            (byte) 0x00,
            (byte) 0x00};
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp != null && resp.length == 19) {
            aplus += (resp[2] & 0xFF) << 24;
            aplus += (resp[1] & 0xFF) << 16;
            aplus += (resp[4] & 0xFF) << 8;
            aplus += (resp[3] & 0xFF);
            aplus *= Ki;
            aplus /= 1000;
            rplus += (resp[10] & 0xFF) << 24;
            rplus += (resp[9] & 0xFF) << 16;
            rplus += (resp[12] & 0xFF) << 8;
            rplus += (resp[11] & 0xFF);
            rplus /= 1000;
            rplus *= Ki;
        } else {
            return null;
        }
        return new AplusRplus(aplus, rplus);
    }

    public AplusRplus getAplusRplusNowDayBegining() {
        double aplus = 0d;
        double rplus = 0d;
        int addr = 0x06A6;
        byte addrHi = (byte) (addr >> 8);
        byte addrLo = (byte) addr;
        byte[] cmd = new byte[]{
            addressOnBus,
            (byte) 0x06,
            (byte) 0x02,
            addrHi,
            addrLo,
            (byte) 0x10,
            (byte) 0x00,
            (byte) 0x00};
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp != null) {
            aplus += (resp[2] & 0xFF) << 24;
            aplus += (resp[1] & 0xFF) << 16;
            aplus += (resp[4] & 0xFF) << 8;
            aplus += (resp[3] & 0xFF);
            aplus *= Ki;
            aplus /= 2000;
            rplus += (resp[10] & 0xFF) << 24;
            rplus += (resp[9] & 0xFF) << 16;
            rplus += (resp[12] & 0xFF) << 8;
            rplus += (resp[11] & 0xFF);
            rplus /= 2000;
            rplus *= Ki;
        } else {
            return null;
        }
        return new AplusRplus(aplus, rplus);
    }

    public AplusRplus getAplusRplusPrevDay() {
        double aplus = 0d;
        double rplus = 0d;
        byte[] cmd = new byte[]{
            addressOnBus,
            (byte) 0x05,
            (byte) 0x50,
            (byte) 0x00,
            (byte) 0x00,
            (byte) 0x00};
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp != null && resp.length == 19) {
            aplus += (resp[2] & 0xFF) << 24;
            aplus += (resp[1] & 0xFF) << 16;
            aplus += (resp[4] & 0xFF) << 8;
            aplus += (resp[3] & 0xFF);
            aplus *= Ki;
            aplus /= 1000;
            rplus += (resp[10] & 0xFF) << 24;
            rplus += (resp[9] & 0xFF) << 16;
            rplus += (resp[12] & 0xFF) << 8;
            rplus += (resp[11] & 0xFF);
            rplus /= 1000;
            rplus *= Ki;
        } else {
            return null;
        }
        return new AplusRplus(aplus, rplus);
    }

    public Byte getMeterAddress() {
        if (addressOnBus == 0) {
            byte[] cmd = new byte[]{
                addressOnBus,
                (byte) 0x08,
                (byte) 0x05,
                (byte) 0x00,
                (byte) 0x00};
            if (!m233lib.sendCMD(cmd)) {
                return null;
            }
            byte[] resp = m233lib.getResponse();
            if (resp != null) {
                return resp[2];
            } else {
                return null;
            }
        } else {
            return addressOnBus;
        }
    }

    public String getMeterSN() {
        byte[] cmd = new byte[]{
            addressOnBus,
            (byte) 0x08,
            (byte) 0x00,
            (byte) 0x00,
            (byte) 0x00};
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp != null) {
            String str, s1, s2, s3, s4;
            s1 = String.valueOf(resp[1]);
            if (s1.length() == 1) {
                s1 = "0" + s1;
            }
            s2 = String.valueOf(resp[2]);
            if (s2.length() == 1) {
                s2 = "0" + s2;
            }
            s3 = String.valueOf(resp[3]);
            if (s3.length() == 1) {
                s3 = "0" + s3;
            }
            s4 = String.valueOf(resp[4]);
            if (s4.length() == 1) {
                s4 = "0" + s4;
            }
            str = s1 + s2 + s3 + s4;
            return str;
        } else {
            return null;
        }
    }

    public Calendar getMeterTime() {
        byte[] cmd = new byte[]{
            addressOnBus,
            (byte) 0x04,
            (byte) 0x00,
            (byte) 0x00,
            (byte) 0x00};
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp == null || resp.length != 11) {
            return null;
        }
        int year, month, day, hour, minute, second;
        year = Integer.parseInt("20" + Integer.toHexString(resp[7] & 0xFF));
        month = Integer.parseInt(Integer.toHexString(resp[6] & 0xFF));
        month--;
        day = Integer.parseInt(Integer.toHexString(resp[5] & 0xFF));
        hour = Integer.parseInt(Integer.toHexString(resp[3] & 0xFF));
        minute = Integer.parseInt(Integer.toHexString(resp[2] & 0xFF));
        second = Integer.parseInt(Integer.toHexString(resp[1] & 0xFF));
        return new GregorianCalendar(year, month, day, hour, minute, second);
    }

    private AvgAR getAvgARAtAddr(int addr) {
        addressInMem3 = addr;
        byte addrHflags = 0;
        if ((addr & 0x10000) == 0x10000) {
            addrHflags |= 128;
        }
        addrHflags |= 3;
        byte addrLo = (byte) addr;
        byte addrHi = (byte) (addr >> 8);
        byte[] cmd = new byte[]{
            addressOnBus,
            (byte) 0x06,
            (byte) addrHflags,
            (byte) addrHi,
            (byte) addrLo,
            (byte) 0x0F,
            (byte) 0x00,
            (byte) 0x00};
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();
        if (resp == null || resp.length < 16) {
            return null;
        }

        int arPeriod = resp[7];

        double Aplus = 0;
        short AplusS = (short) ((resp[9] & 0xFF) << 8);
        AplusS |= resp[8] & 0xFF;
        if ((AplusS & 0xFFFF) != 0xFFFF) {
            Aplus = AplusS & 0xFFFF;
        }
        Aplus *= 60 / arPeriod;
        Aplus /= 2;
        Aplus /= meterConst;
        Aplus *= Ki;

        double Aminus = 0;
        short AminusS = (short) ((resp[11] & 0xFF) << 8);
        AminusS |= resp[10] & 0xFF;
        if ((AminusS & 0xFFFF) != 0xFFFF) {
            Aminus = AminusS & 0xFFFF;
        }
        Aminus *= 60 / arPeriod;
        Aminus /= 2;
        Aminus /= meterConst;
        Aminus *= Ki;

        double Rplus = 0;
        short RplusS = (short) ((resp[13] & 0xFF) << 8);
        RplusS |= resp[12] & 0xFF;
        if ((RplusS & 0xFFFF) != 0xFFFF) {
            Rplus = RplusS & 0xFFFF;
        }
        Rplus *= 60 / arPeriod;
        Rplus /= 2;
        Rplus /= meterConst;
        Rplus *= Ki;

        double Rminus = 0;
        short RminusS = (short) ((resp[15] & 0xFF) << 8);
        RminusS |= resp[14] & 0xFF;
        if ((RminusS & 0xFFFF) != 0xFFFF) {
            Rminus = RminusS & 0xFFFF;
        }
        Rminus *= 60 / arPeriod;
        Rminus /= 2;
        Rminus /= meterConst;
        Rminus *= Ki;

        int year, month, day, hour, minute;
        year = Integer.parseInt("20" + Integer.toHexString(resp[6] & 0xFF));
        month = Integer.parseInt(Integer.toHexString(resp[5] & 0xFF));
        month--;
        day = Integer.parseInt(Integer.toHexString(resp[4] & 0xFF));
        hour = Integer.parseInt(Integer.toHexString(resp[2] & 0xFF));
        minute = Integer.parseInt(Integer.toHexString(resp[3] & 0xFF));

        return new AvgAR(Aplus, Aminus, Rplus, Rminus, new GregorianCalendar(year, month, day, hour, minute), arPeriod);
    }

    public AvgAR getAvgARLast() {
        byte[] cmd = {
            addressOnBus,
            (byte) 0x08,
            (byte) 0x13,
            (byte) 0x00,
            (byte) 0x00};
        if (!m233lib.sendCMD(cmd)) {
            return null;
        }
        byte[] resp = m233lib.getResponse();

        if ((resp[3] & 1) == 1) {
            overloadBit = true;
        } else {
            overloadBit = false;
        }

        int address = 0;

        if ((resp[1] & 16) == 16) {
            address |= 0x10000;
        }

        byte adrHi = resp[1];
        byte adrLo = resp[2];
        short adrHL = (short) ((adrHi & 0xFF) << 8);
        adrHL |= adrLo & 0xFF;
        adrHL = (short) (adrHL << 4);
        address |= adrHL & 0xFFFF;
        return getAvgARAtAddr(address);
    }

    public AvgAR getAvgARPrev() {
        if (addressInMem3 < 0x10) {
            // Сделать проверку на количество памяти счетчика
            return getAvgARAtAddr(0x1FFF0);
        } else {
            return getAvgARAtAddr(addressInMem3 - 0x10);
        }
    }

    public AvgAR getAvgARNext() {
        if (addressInMem3 >= 0x1FFF0) {
            // Сделать проверку на количество памяти счетчика
            return getAvgARAtAddr(0x00000);
        } else {
            return getAvgARAtAddr(addressInMem3 + 0x10);
        }
    }

    public AvgAR getAvgARCurr() {
        return getAvgARAtAddr(addressInMem3);
    }

    public int getDeepInMins() {
        AvgAR aar = getAvgARLast();
        if (overloadBit) {
            return 8192 * aar.getArPeriod();
        }
        return addressInMem3 * aar.getArPeriod();
    }
}
